package com.example.novelweb.controller;

import com.example.novelweb.common.BaseResponse;
import com.example.novelweb.common.ErrorCode;
import com.example.novelweb.common.ResultUtils;
import com.example.novelweb.constant.UserConstant;
import com.example.novelweb.exception.BusinessException;
import com.example.novelweb.model.vo.UserVO;
import com.example.novelweb.utils.FileUtils;
import com.example.novelweb.utils.UserUtils;
import io.swagger.annotations.ApiImplicitParam;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;

@RestController
public class FileController {

  private final Path chapterResPath = Paths.get(UserConstant.CHAPTER_RES_TXT_PATH).toAbsolutePath().normalize();


// upload Chapter => ChapterController.uploadChapter()
// TODO: when chapter.status == 0  => reject() , 设计成直接通过chapterId获取??
// TODO: /res/novels/{novelId}/filename(!! no ".txt" !!) , 直接自己读取文件，返回String
  @GetMapping("/res/novels/{novelId}/{filename:.+}")
  public ResponseEntity<Resource> getChapterRes(@PathVariable String novelId, @PathVariable String filename) {
    try {
      Path filePath = chapterResPath.resolve(novelId).resolve(filename).normalize();
      Resource resource = new UrlResource(filePath.toUri());

      if(resource.exists() || resource.isReadable()) {
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_TYPE, "text/plain; charset=UTF-8");

        return ResponseEntity.ok().headers(headers).body(resource);
      } else {
        return ResponseEntity.notFound().build();
//        throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
      }
    } catch (MalformedURLException e) {
      return ResponseEntity.internalServerError().build();
//      throw new BusinessException(ErrorCode.SYSTEM_ERROR);
    }
  }

  @ApiImplicitParam(name = "Authorization", value = "Authorization",required = true, dataType = "String",paramType="header")
  @PostMapping("/res/images")
  public BaseResponse<String> uploadImg(@RequestParam("file") MultipartFile file, HttpServletRequest httpServletRequest) {
    // 校验已登录
    UserVO userVO = UserUtils.LoginCheck();
    if( userVO== null) {
      throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR,"用户未登录");
    }
    // file.contentType
    String contentType = file.getContentType();
    if (contentType == null || !contentType.startsWith("image/")) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR,"仅支持上传图片文件");
    }
    // file.size
    if(file.getSize() > UserConstant.MAX_IMG_SIZE) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR,"文件大小>3M");
    }

    try {
      Path imgPath = Paths.get(UserConstant.IMG_RES_PATH).toAbsolutePath().normalize();
      if(!Files.exists(imgPath)) {
        Files.createDirectories(imgPath);
      }

      String fileName = FileUtils.uniqueFileNameGenerate(file.getOriginalFilename());
      Path filePath = imgPath.resolve(fileName);

      asyncSaveFile(file,filePath);

      return ResultUtils.success(UserConstant.SERVER_URL_PREFIX + "images/" +fileName);
    } catch (IOException e) {
      throw new BusinessException(ErrorCode.SYSTEM_ERROR,"上传保存失败");
    }

  }

// private functions:

  @Async
  protected void asyncSaveFile(MultipartFile file, Path filePath) throws IOException {
    Files.copy(file.getInputStream(),filePath, StandardCopyOption.REPLACE_EXISTING);
  }



}
